import { request } from 'umi';
import { delay, setStorage } from '@wowon/utils';
import { STORAGE_NAMES } from '@/common/constant';

let refreshPromise;
async function refreshToken(refresh) {
  if (!refreshPromise) {
    refreshPromise = new Promise((resolve) => {
      refresh().then((result) => {
        if (result.code === '0') {
          setStorage(STORAGE_NAMES.token, `${result.access_type} ${result.access_token}`);
        }
        resolve(result.code === '0');
        refreshPromise = null;
      });
    });
  }
  return refreshPromise;
}

const response = (option = {}) => {
  const { refresh, onSuccess, onFail } = option;

  let timer = null;
  let req_count = 0;

  const reponseHandler = async function (response) {
    if (response.status === 401) {
      const success = await refreshToken(refresh);

      if (success) {
        onSuccess?.();
      } else {
        onFail?.();
      }
    }

    return response;
  };

  const errorHandler = async function (error) {
    if (!!error.response && error.response.status === 401 && req_count < 2) {
      req_count++;

      clearTimeout(timer);
      timer = setTimeout(() => {
        req_count = 0;
      }, 5000);

      const success = await refreshToken(refresh);

      if (success) {
        onSuccess?.();
        await delay(2000);
        error.config.headers = error.config.getHeaders();
        const data = await request(error.config.url, {
          ...error.config,
          requestInterceptors: void 0,
          responseInterceptors: void 0,
        });

        error.response.data = data;
        error.response.status = 200;
        error.response.statusText = 'OK';

        return error.response;
      } else {
        onFail?.();
      }
    }

    return error;
  };

  return [reponseHandler, errorHandler];
};

export default { request: null, response };
